﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RemoteManger
{
    public static class ObjectExtends
    {
        /// <summary>
        /// 将数据转为json（实体上无需标记）
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string ToJson(this object data)
        {
            JsonSerializerSettings settings = new()
            {
                NullValueHandling = NullValueHandling.Ignore,
                DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore
            };
            return JsonConvert.SerializeObject(data, settings);
        }


        /// <summary>
        /// 序列化（实体上无需标记）
        /// </summary>
        /// <param name="data">需要序列化的对象</param>
        /// <returns></returns>
        public static T? ToObject<T>(this string data)
        {
            JsonSerializerSettings settings = new JsonSerializerSettings()
            {
                NullValueHandling = NullValueHandling.Ignore,
                DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore
            };
            return JsonConvert.DeserializeObject<T>(data, settings);
        }


        /// <summary>
        /// 对象转为字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ToNullString(this object? obj)
        {
            if (obj != null || obj == DBNull.Value)
            {
                string? val = obj.ToString();
                if (val == null) return string.Empty;
                return val.ToString();
            }
            return string.Empty;
        }

        /// <summary>
        /// 对象转字符串去掉空格
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ToNullStringNoSpace(this object? obj)
        {
            if (obj != null || obj == DBNull.Value)
            {
                string? val = obj.ToString();
                if (val == null) return string.Empty;
                return val.Trim();
            }
            return string.Empty;
        }
        /// <summary>
        /// 对象转换整数
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static int ToInt(this object obj)
        {
            if (obj == null || obj == DBNull.Value) return 0;
            if (typeof(decimal) == obj.GetType())
                obj = Math.Floor((decimal)obj);
            else if (typeof(double) == obj.GetType())
                obj = Math.Floor((double)obj);
            else if (typeof(string) == obj.GetType() && obj.ToNullString().IndexOf('.') > -1)
                obj = obj.ToNullString().Substring(0, obj.ToNullString().IndexOf('.'));
            string nullString = obj.ToNullString();
            if (int.TryParse(nullString, out int result))
            {
                return result;
            }
            return 0;
        }

        /// <summary>
        /// 转换bit值
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool ToBool(this object obj)
        {
            string nullString = obj.ToNullString();
            if (nullString == "1") return true;
            if (nullString.ToLower() == "true") return true;
            if (bool.TryParse(nullString, out bool result))
            {
                return result;
            }
            return false;
        }

        /// <summary>
        /// 对象转Long
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static long ToLong(this object obj)
        {
            string nullString = obj.ToNullString();
            if (long.TryParse(nullString, out long result))
            {
                return result;
            }
            return 0;
        }

        /// <summary>
        /// 对象转Double
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static double ToDouble(this object obj)
        {
            string nullString = obj.ToNullString();
            if (double.TryParse(nullString, out double result))
            {
                return result;
            }
            return 0.0;
        }

        /// <summary>
        /// 对象转Decimal
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static decimal ToDecimal(this object obj)
        {
            string nullString = obj.ToNullString();
            if (decimal.TryParse(nullString, out decimal result))
            {
                return result;
            }
            return 0;
        }

        public static float ToFloat(this object obj)
        {
            string nullString = obj.ToNullString();
            float result = 0.0f;
            float.TryParse(nullString, out result);
            return result;
        }

        /// <summary>
        ///  对象转DateTime
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static DateTime? ToDateTime(this object obj)
        {
            string nullString = obj.ToNullString();
            if (DateTime.TryParse(nullString, out DateTime result))
            {
                if (result == DateTime.MinValue) return new DateTime?();
                return new DateTime?(result);
            }
            return new DateTime?();
        }



        /// <summary>
        /// 获取传入日期的周一的日期时间
        /// </summary>
        /// <returns>返回格式为"2022-01-01"</returns>
        public static DateTime GetMonday(this DateTime time)
        {
            DateTime temp = new DateTime(time.Year, time.Month, time.Day);
            int count = time.DayOfWeek - DayOfWeek.Monday;
            if (count == -1) count = 6;
            return temp.AddDays(-count).Date;
        }


        /// <summary>
        /// DateTime转时间戳
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public static long ToTimeStamp(this DateTime time)
        {
            return Convert.ToInt64((time - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds);
        }

        #region 设备MAC的字符串转Long

        /// <summary>
        /// MAC字符串转long
        /// </summary>
        /// <param name="mac"></param>
        /// <returns></returns>
        public static long MacStringToLong(string mac)
        {
            return Convert.ToInt64(mac.Replace(":", ""), 16);
        }

        /// <summary>
        /// LONG转MAC字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string MacLongToString(long obj)
        {

            string hexString = obj.ToString("X");
            hexString = hexString.PadLeft(12, '0');
            string macAddress = $"{hexString.Substring(0, 2)}:{hexString.Substring(2, 2)}:{hexString.Substring(4, 2)}:" +
                                       $"{hexString.Substring(6, 2)}:{hexString.Substring(8, 2)}:{hexString.Substring(10, 2)}";
            //Console.WriteLine(macAddress);

            //// 添加分隔符将字符串转换为 MAC 地址格式
            //string[] a = SplitStringEvery(Convert.ToString(obj, 16), 2);
            //return string.Join(":", SplitStringEvery(Convert.ToString(obj, 16), 2));
            return macAddress;
        }

        private static string[] SplitStringEvery(string input, int length)
        {
            int index = 0;
            var substrings = new string[(input.Length + length - 1) / length];

            for (int i = 0; i < input.Length; i += length)
            {
                substrings[index] = input.Substring(i, Math.Min(length, input.Length - i));
                index++;
            }

            return substrings;
        }

        #endregion

        /// <summary>
        /// 深克隆对象
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        //public static T? Clone<T>(this T data)
        //{
        //    return JsonHelper.ToObject<T>(JsonHelper.ToJson(data));
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        public static byte ToBrushByte(this string obj, int offset)
        {
            return Convert.ToByte(obj.Substring((offset - 1) * 2, 2), 16);
        }
        private static string keys = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-";//64进制的。
        private static int exponent = keys.Length;//幂数
        /// <summary>
        /// 将64进制转换为10进制
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static long ToStr64ToLong(this string value)   //bUI6zOLZTrj
        {
            long result = 0;
            for (int i = 0; i < value.Length; i++)
            {
                int x = value.Length - i - 1;
                result += keys.IndexOf(value[i]) * Pow(exponent, x);// Math.Pow(exponent, x);
            }
            return result;
        }
        /// <summary>
        /// 一个数据的N次方
        /// </summary>
        /// <param name="baseNo"></param>
        /// <param name="x"></param>
        /// <returns></returns>
        private static long Pow(int baseNo, int x)
        {
            int value = 1;////1 will be the result for any number's power 0.任何数的0次方，结果都等于1
            while (x > 0)
            {
                value = value * baseNo;
                x--;
            }
            return value;
        }
    }
}
